package com.gblfy.httpclinet.util;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.RequestEntity;
import org.apache.commons.httpclient.methods.StringRequestEntity;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * httpclient统一处理工具类
 *
 * @author gblfy
 * @date 2021-10-12
 */
public class HttpClientUtil {

    private static Logger log = LoggerFactory.getLogger(HttpClientUtil.class);

    //连接超时时间
    public static final int CONNECT_TIMEOUT = 5000;
    public static final int CONNECT_REQUEST_TIMEOUT = 1000;
    public static final int SOCKET_TIMEOUT = 60000;

    private HttpClientUtil() {
    }

    private static RequestConfig requestConfig = RequestConfig.custom()
            .setConnectTimeout(CONNECT_TIMEOUT).setConnectionRequestTimeout(CONNECT_REQUEST_TIMEOUT)
            .setSocketTimeout(SOCKET_TIMEOUT).build();

    /**
     * 处理httpClient get请求（有参）
     *
     * @param url   第三方调用地址
     * @param param 入参
     * @return
     */
    public static String doGet(String url, Map<String, String> param) {

        // 创建Httpclient对象
        CloseableHttpClient httpclient = HttpClients.createDefault();

        String resultString = null;
        CloseableHttpResponse response = null;
        try {
            // 创建uri
            URIBuilder builder = new URIBuilder(url);
            if (param != null) {
                for (String key : param.keySet()) {
                    builder.addParameter(key, param.get(key));
                }
            }
            URI uri = builder.build();

            // 创建http GET请求
            HttpGet httpGet = new HttpGet(uri);
            httpGet.setConfig(requestConfig);
            // 执行请求
            response = httpclient.execute(httpGet);
            // 判断返回状态是否为200
            if (response.getStatusLine().getStatusCode() == 200) {
                resultString = EntityUtils.toString(response.getEntity(), "UTF-8");
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        } finally {
            try {
                if (response != null) {
                    response.close();
                }
                httpclient.close();
            } catch (IOException e) {
                log.error(e.getMessage(), e);
            }
        }
        return resultString;
    }

    /**
     * 处理httpClient get请求（无参）
     *
     * @param url 第三方调用地址
     * @return
     */
    public static String doGet(String url) {
        return doGet(url, null);
    }


    /**
     * 处理httpClient post请求（有参非json）
     *
     * @param url   第三方调用地址
     * @param param 入参
     * @return
     */
    public static String doPost(String url, Map<String, Object> param) {
        // 创建Httpclient对象
        CloseableHttpClient httpClient = HttpClients.createDefault();
        CloseableHttpResponse response = null;
        String resultString = "";
        try {
            // 创建Http Post请求
            HttpPost httpPost = new HttpPost(url);
            httpPost.setConfig(requestConfig);
            // 创建参数列表
            if (param != null) {
                List<NameValuePair> paramList = new ArrayList<>();
                for (String key : param.keySet()) {
                    paramList.add(new BasicNameValuePair(key, (String) param.get(key)));
                }
                // 模拟表单
                UrlEncodedFormEntity entity = new UrlEncodedFormEntity(paramList);
                httpPost.setEntity(entity);
            }
            // 执行http请求
            response = httpClient.execute(httpPost);
            resultString = EntityUtils.toString(response.getEntity(), "utf-8");
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        } finally {
            try {
                if (response != null) {
                    response.close();
                }
                httpClient.close();
            } catch (IOException e) {
                log.error(e.getMessage(), e);
            }
        }

        return resultString;
    }

    /**
     * 处理httpClient post请求（无参）
     *
     * @param url 第三方调用地址
     * @return
     */
    public static String doPost(String url) {
        return doPost(url, null);
    }

    /**
     * 协议类型：
     * HTTP 请求方式：POST 报文格式:json 编码设置：UTF-8 响应类型：jsonStr
     *
     * @param url     请求地址
     * @param json    请求报文
     * @return
     * @throws Exception
     */
    public static String postJosnContent(String url, String json) throws Exception {
        System.out.println("请求接口参数：" + json);
        HttpClient httpClient = new HttpClient();
        httpClient.getHttpConnectionManager().getParams().setSoTimeout(CONNECT_TIMEOUT);
        PostMethod method = new PostMethod(url);
        try {
            RequestEntity entity = new StringRequestEntity(json, "application/json", "UTF-8");
            method.setRequestEntity(entity);
            httpClient.executeMethod(method);
            System.out.println("请求接口路径url：" + method.getURI().toString());
            InputStream in = method.getResponseBodyAsStream();
            // 下面将stream转换为String
            StringBuffer sb = new StringBuffer();
            InputStreamReader isr = new InputStreamReader(in, "UTF-8");
            char[] b = new char[4096];
            for (int n; (n = isr.read(b)) != -1; ) {
                sb.append(new String(b, 0, n));
            }
            String returnStr = sb.toString();
            System.out.println("响应报文:" + returnStr);
            return returnStr;
        } catch (Exception e) {
            e.printStackTrace();
            throw e;
        } finally {
            method.releaseConnection();
        }
    }

    // -------------------------------------------单元测试---------------------------------------
//	public static void main(String[] args) throws Exception {
//
//		// 客户端发送
////		 String url = "http://192.168.180.143:8085/wx/token/getAccessToken.gsp";
////		 String json = "{\"name\":\"gblfy\"}";
//		 String url = "https://open-api.medbanks-test.com/open/api/medbanks.trading_order.insured";
//		 String json = "{\\r\\n\" + \r\n" +
//		 		"    			\"\\\"data\\\":\\\"ApYnXBUJeOnPOYpaM8REL7w3IgFceE2kejczj0cJ1yjlS8wdqS+YQu7JlEQyRIDqs\\r\\n\" + \r\n" +
//		 		"    			\"0oKjrvtdsidjk/+r0pYFhauEMjzktfxAKUh87SwCMIADR44rxV/iwn3cmJHEHOCMN0AGq7RQn\\r\\n\" + \r\n" +
//		 		"    			\"kIEHJEE0whmsaPv+H7usCq6VkhwA/7hic+ISEhvLuoBhBTcR1oio0KVDq/80nTf181CX6S8x2B\\r\\n\" + \r\n" +
//		 		"    			\"FrViDSEnKkCX5heWg7jnXlckY9htgzHYs02qM2WkK7/n9JG2qUFVnoVD14eGw0WF2KPbTvE\\r\\n\" + \r\n" +
//		 		"    			\"04TKW/y76TvLU/ZMIjdC+hUEIfsaL7uqfZ7O4vO6PWbQigYS0ulqANe+Evn5yil/DhBnr2Zo5z\\r\\n\" + \r\n" +
//		 		"    			\"3+XmjilR+XbuPFKpXki/Zo+WFCymxQce3kXzoIGLNd7lWacoHb7jsMHqk0Q+COVmtObRQ\\r\\n\" + \r\n" +
//		 		"    			\"8=\\\",\\r\\n\" + \r\n" +
//		 		"    			\"\\\"requestId\\\": \\\"490d4921a7db4680938d2aeb36c01e79\\\"\\r\\n\" + \r\n" +
//		 		"    			\"}";
//		 String res = postJosnContent(url, json,5000);
//		 System.out.println("响应报文:" + res);
//
//		// 服务端接收
//		// @RequestMapping(value = "/postToJson", method = RequestMethod.POST,produces =
//		// "application/json;charset=UTF-8")
//		// @ResponseBody
//		// public String postToJson(@RequestBody String json) {
//		// System.out.println(json);
//		// return json;
//	}
}
